package org.lonetree.experiments.hib;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibTestServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
	static final long serialVersionUID = 1L;
	
	private static final String HIBERNATE_CFG_XML	= "org/lonetree/tc/dao/hibernate/hibernate.cfg.xml";
	private static final String HIBERNATE_ID		= "id";
	private static final String HIBERNATE_TEXT		= "text";
	private static final String BR					= "<br />";
	private static final String NBSP				= "&nbsp;";
	private static final String INDENT				= NBSP + NBSP + NBSP + NBSP;
	
	public HibTestServlet() {
		super();
	}   	
	
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		PrintWriter pw = res.getWriter();
		printHtmlPrologue(pw);
		
		pw.println("Hibernate Test servlet" + BR + BR);
		try{
			String param = req.getParameter(HIBERNATE_ID);
			if(param == null)
				throw new NullPointerException("the GET must carry an \"id\" parameter");
			Long id = new Long(param);
			
			param = req.getParameter(HIBERNATE_TEXT);
			if(param == null)
				throw new NullPointerException("the GET must carry a \"text\" parameter");
			
			testHibernateConnection(pw, id, param);
		}
		catch(Exception e){
			e.printStackTrace();
			pw.println(BR + "<font color=\"#FF0000\">");
			pw.println("Caught an exception. Printing stack trace (check server log). Exception: " + e.toString().replaceAll("\n", BR));
			pw.println("</font>");
		}
		
		printHtmlEpilogue(pw);
	}
	
	private static void printHtmlPrologue(PrintWriter pw){
		pw.println("<html><head><title>Hibernate Test Servlet</title></head><body>");
	}
	
	private static void printHtmlEpilogue(PrintWriter pw){
		pw.println("</body></html>");
	}
	
	private static String strongHtml(String str){
		return "<strong>" + str + "</strong>";	
	}

	@SuppressWarnings("unchecked")
	private static void testHibernateConnection(PrintWriter pw, Long id, String text) throws Exception{
		pw.println(strongHtml("Testing Hibernate Connection...") + BR);
		
		SessionFactory sf = new Configuration().configure(HIBERNATE_CFG_XML).buildSessionFactory();
		
		pw.println(INDENT + "Opening first session and beginning first transaction" + BR);
		Session session1 = sf.openSession();
		Transaction tx1 = session1.beginTransaction();
		
		pw.println(INDENT + "Creating BusinessExample with ID = [" + id + "] and text = \"" + text + "\"" + BR);
		BusinessExample ex = new BusinessExample();
		ex.setId(id);
		ex.setText(text);
		
		pw.println(INDENT + "Saving BusinessExample to DB" + BR);
		Long msgId = (Long)session1.save(ex);
		pw.println(INDENT + "The msgId is of the stored example is " + msgId + BR);

		pw.println(INDENT + "Commiting first transaction and closing first session" + BR);
		tx1.commit();
		session1.close();

		pw.println(INDENT + "Opening second session and beginning second transaction" + BR);
		Session session2 = sf.openSession();
		Transaction tx2 = session2.beginTransaction();
		
		pw.println(INDENT + "Retrieving list of BusinessExample(s) from DB" + BR);
		List<BusinessExample> examples = session2.createQuery("from BusinessExample b order by b.text asc").list();
		pw.println(INDENT + examples.size() + " BusinessExample(s) found:" + BR);
		for(Iterator<BusinessExample> it = examples.iterator(); it.hasNext();){
			BusinessExample retrEx = it.next();
			pw.println(INDENT + INDENT + retrEx.getId() + ": " + retrEx.getText() + BR);
		}
		
		pw.println(INDENT + "Commiting second transaction and closing second session" + BR);
		tx2.commit();
		session2.close();

		//HibernateUtil.shutdown();
		
		pw.println("<font color=\"#00FF00\">");
		pw.println("Hibernate connection test complete");
		pw.println("</font>");
	}
}